STM32H7B0VBT6使用Free RTOS配置SD卡+Fatfs文件管理系统

您所在的位置:网站首页 free loop怎么念 STM32H7B0VBT6使用Free RTOS配置SD卡+Fatfs文件管理系统

STM32H7B0VBT6使用Free RTOS配置SD卡+Fatfs文件管理系统

#STM32H7B0VBT6使用Free RTOS配置SD卡+Fatfs文件管理系统| 来源: 网络整理| 查看: 265

作者:Jack_G 时间:2023.05.26 版本:V1.0 上次修改时间: 环境: \quad \quad \quad \quad STM32Cube MX V6.8.1 \quad \quad \quad \quad STM32CubeH7 Firmware Package V1.11.0 / 04-Nov-2022 \quad \quad \quad \quad Fatfs: R0.12C \quad \quad \quad \quad Keil: V5.29

文章目录 前言一、基本配置1.1 配置时钟源为外部晶振1.2 配置烧录程序的引脚1.3 配置时钟树,配置主频280M 二、配置SDMMC三、配置FreeRTOS四、配置Fatfs五、修改堆栈六、增加测试代码

前言

裸机使用Fatfs时,没有任何问题,加入Free RTOS后就一直不能f_mount,返回值一直为1,百思不得其解,几经周转,最后重新配置了一次就正常使用了,具体配置过程如下:

一、基本配置 1.1 配置时钟源为外部晶振

在这里插入图片描述

1.2 配置烧录程序的引脚

在这里插入图片描述

1.3 配置时钟树,配置主频280M

在这里插入图片描述

`注意:其中:使用SD卡时,SDMMC时钟常配为48 MHz,经过分频后不超过25MHz`(但是经过实际我测试,我配置的280 MHz,SDMMC分频系数为5也能使用,即:280/(2*5) = 28 MHz,想提速考虑这部分再斟酌)

在这里插入图片描述 配置个串口用于信息打印测试

在这里插入图片描述

二、配置SDMMC

选择四线模式,分频系数我写的5(速度较低)。 在这里插入图片描述

查了一些博客,有的同学反映需要将数据线和命令先上拉,不然有可能出现f_mount失败的情况,修改引脚上下拉再DPIO中修改 在这里插入图片描述 使能SDMMC的中断,在配置完Free RTOS后优先级会自动变为5 在这里插入图片描述

三、配置FreeRTOS

将heap改大一点 在这里插入图片描述 将初始任务的堆栈改大一点 在这里插入图片描述

四、配置Fatfs

修改支持长文件名和MAX_SS 不建议在此单片机开启文件名的中文支持,因为RAM不够, 配置

五、修改堆栈

增大堆栈空间 在这里插入图片描述

最后生成代码即可

六、增加测试代码 在main.c中添加fputc重定义一下printf 添加头文件 /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include /* USER CODE END Includes */

重定向fputc

/* USER CODE BEGIN 4 */ //重定向fputc函数printf int fputc(int ch,FILE *f){ HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,HAL_MAX_DELAY); return ch; } //重定向fgetc函数 scanf int fgetc(FILE *f){ uint8_t ch; HAL_UART_Receive(&huart1,(uint8_t *)&ch,1,HAL_MAX_DELAY); return ch; } /* USER CODE END 4 */ 在freertos.c中添加测试代码 (Fatfs的初始化啥的都在任务中进行初始化)

这部分是添加的测试函数代码

#include "fatfs.h" #include "sdmmc.h" #include #define FF_MAX_SS 4096 // 函数:FatFs_FileTest // 功能:进行文件写入和读取测试 // uint8_t FatFs_FileTest(void) //文件创建和写入测试 { uint8_t i = 0; uint16_t BufferSize = 0; FIL MyFile; // 文件对象 UINT MyFile_Num; // 数据长度 BYTE MyFile_WriteBuffer[] = "STM32H7B0 SD卡 文件系统测试"; //要写入的数据 BYTE MyFile_ReadBuffer[1024]; //要读出的数据 uint8_t MyFile_Res; /* Return value for SD */ printf("-------------FatFs 文件创建和写入测试---------------\r\n"); MyFile_Res = f_open(&MyFile,"0:FatFs Test.txt",FA_CREATE_ALWAYS | FA_WRITE); //打开文件,若不存在则创建该文件 if(MyFile_Res == FR_OK) { printf("文件打开/创建成功,准备写入数据...\r\n"); MyFile_Res = f_write(&MyFile,MyFile_WriteBuffer,sizeof(MyFile_WriteBuffer),&MyFile_Num); //向文件写入数据 if (MyFile_Res == FR_OK) { printf("写入成功,写入内容为:\r\n"); printf("%s\r\n",MyFile_WriteBuffer); } else { printf("文件写入失败,请检查SD卡或重新格式化!\r\n"); f_close(&MyFile); //关闭文件 return ERROR; } f_close(&MyFile); //关闭文件 } else { printf("无法打开/创建文件,请检查SD卡或重新格式化!\r\n"); f_close(&MyFile); //关闭文件 return ERROR; } printf("-------------FatFs 文件读取测试---------------\r\n"); BufferSize = sizeof(MyFile_WriteBuffer)/sizeof(BYTE); // 计算写入的数据长度 MyFile_Res = f_open(&MyFile,"0:FatFs Test.txt",FA_OPEN_EXISTING | FA_READ); //打开文件,若不存在则创建该文件 MyFile_Res = f_read(&MyFile,MyFile_ReadBuffer,BufferSize,&MyFile_Num); // 读取文件 if(MyFile_Res == FR_OK) { printf("文件读取成功,正在校验数据...\r\n"); for(i=0;i printf("校验失败,请检查SD卡或重新格式化!\r\n"); f_close(&MyFile); //关闭文件 return ERROR; } } printf("校验成功,读出的数据为:\r\n"); printf("%s\r\n",MyFile_ReadBuffer); } else { printf("无法读取文件,请检查SD卡或重新格式化!\r\n"); f_close(&MyFile); //关闭文件 return ERROR; } f_close(&MyFile); //关闭文件 return SUCCESS; } // 函数:FatFs_GetVolume // 功能:计算设备的容量,包括总容量和剩余容量 void FatFs_GetVolume(void) // 计算设备容量 { FATFS *fs; //定义结构体指针 uint32_t SD_CardCapacity = 0; //SD卡的总容量 uint32_t SD_FreeCapacity = 0; //SD卡空闲容量 DWORD fre_clust, fre_sect, tot_sect; //空闲簇,空闲扇区数,总扇区数 f_getfree("0:",&fre_clust,&fs); //获取SD卡剩余的簇 tot_sect = (fs->n_fatent-2) * fs->csize; //总扇区数量 = 总的簇 * 每个簇包含的扇区数 fre_sect = fre_clust * fs->csize; //计算剩余的可用扇区数 SD_CardCapacity = tot_sect / 2048 ; // SD卡总容量 = 总扇区数 * 512( 每扇区的字节数 ) / 1048576(换算成MB) SD_FreeCapacity = fre_sect / 2048 ; //计算剩余的容量,单位为M printf("-------------------获取设备容量信息-----------------\r\n"); printf("SD容量:%dMB\r\n",SD_CardCapacity); printf("SD剩余:%dMB\r\n",SD_FreeCapacity); } void FatFs_Check(void) //判断FatFs是否挂载成功,若没有创建FatFs则格式化SD卡 { BYTE work[FF_MAX_SS]; FATFS_LinkDriver(&SD_Driver, SDPath); // 初始化驱动 retSD = f_mount(&SDFatFS,"0:",1); // 挂载SD卡 if (retSD == FR_OK) //判断是否挂载成功 { printf("\r\nSD文件系统挂载成功\r\n"); FatFs_GetVolume(); } else { if(retSD == 13) { printf("SD卡还未创建文件系统,即将格式化\r\n"); retSD = f_mkfs("0:",FM_FAT32,0,work,sizeof work); //格式化SD卡,FAT32,簇默认大小16K if (retSD == FR_OK) //判断是否格式化成功 printf("SD卡格式化成功!\r\n"); else printf("格式化失败,请检查或更换SD卡!\r\n"); } else printf("挂载失败:%d\r\n",retSD); } } void printf_sdcard_info(void) { HAL_SD_CardInfoTypeDef SDCardInfo; uint64_t CardCap; //SD卡容量 HAL_SD_CardCIDTypeDef SDCard_CID; HAL_SD_GetCardCID(&hsd1,&SDCard_CID); //获取CID HAL_SD_GetCardInfo(&hsd1,&SDCardInfo); //获取SD卡信息 CardCap=(uint64_t)(SDCardInfo.LogBlockNbr)*(uint64_t)(SDCardInfo.LogBlockSize); //计算SD卡容量 switch(SDCardInfo.CardType) { case CARD_SDSC: { if(SDCardInfo.CardVersion == CARD_V1_X) printf("Card Type:SDSC V1\r\n"); else if(SDCardInfo.CardVersion == CARD_V2_X) printf("Card Type:SDSC V2\r\n"); } break; case CARD_SDHC_SDXC:printf("Card Type:SDHC\r\n");break; default:break; } printf("Card ManufacturerID: %d \r\n",SDCard_CID.ManufacturerID); //制造商ID printf("CardVersion: %d \r\n",(uint32_t)(SDCardInfo.CardVersion)); //卡版本号 printf("Class: %d \r\n",(uint32_t)(SDCardInfo.Class)); // printf("Card RCA(RelCardAdd):%d \r\n",SDCardInfo.RelCardAdd); //卡相对地址 printf("Card BlockNbr: %d \r\n",SDCardInfo.BlockNbr); //块数量 printf("Card BlockSize: %d \r\n",SDCardInfo.BlockSize); //块大小 printf("LogBlockNbr: %d \r\n",(uint32_t)(SDCardInfo.LogBlockNbr)); //逻辑块数量 printf("LogBlockSize: %d \r\n",(uint32_t)(SDCardInfo.LogBlockSize)); //逻辑块大小 printf("Card Capacity: %d MB\r\n",(uint32_t)(CardCap>>20)); //卡容量 }

最后在任务中进行调用即可 示例:

/* USER CODE END Header_StartDefaultTask */ void StartDefaultTask(void *argument) { /* USER CODE BEGIN StartDefaultTask */ /* Infinite loop */ FatFs_Check(); printf_sdcard_info(); FatFs_FileTest(); for(;;) { HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin); osDelay(1000); } /* USER CODE END StartDefaultTask */ }

附上工程代码



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3